from toolSettingUi import Ui_ToolSetting
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QPushButton, QWidget, QAction
from testerToolUi import Ui_TesterToolUi
from PyQt5 import QtCore, QtGui
import typing
import sys
import logging
import binascii
import threading
import queue

from toolUds import ToolUds
from toolSetting import ToolSetting
from udsConsole import UdsConsole
from TestCase.testCase import TestCase
from Trace.toolMsgTrace import ToolTrace
from Trace.toolTraceSetting import ToolTraceSetting

LOGGING_NAME = 'MainWindow'

class Stream(QtCore.QObject):

    newText = pyqtSignal(str)
        
    def write(self, text):
        
        self.newText.emit(str(text))
        
    def flush(self):
        pass

class MainWindow(QMainWindow,Ui_TesterToolUi):

    def __init__(self) -> None:
        super(MainWindow, self).__init__()

        sys.stdout = Stream(newText=self.onUpdateText)

        self.testerForm = Ui_TesterToolUi()
        self.setupUi(self)

        
        self.initStatus = 0
        self.canMsgRecFlag = True
        self.canMsgRecQueue = queue.Queue()

        self.testerTool = ToolUds(self)
        self.testerToolSettingForm = ToolSetting(self)
        self.testerToolUdsConsole = UdsConsole(self)
        self.testerToolCase = TestCase(self)
        self.testerToolMsg = ToolTrace(self)
        self.testerToolMsgSetting = ToolTraceSetting(self)

        # TextEdit Color
        pal = QtGui.QPalette()
        pal.setColor(QtGui.QPalette.Base, QtGui.QColor(43, 43, 43))
        pal.setColor(QtGui.QPalette.Text, QtGui.QColor(169, 183, 198))
        self.LogtextEdit.setPalette(pal)

        #action
        self.actionSetting.triggered.connect(self.toolSettingTriggered)
        self.actionUdsConsole.triggered.connect(self.toolUdsConsoleTriggered)
        self.SendlineEdit.returnPressed.connect(self.toolSendUdsMsg)
        self.SendpushButton.clicked.connect(self.toolSendUdsMsg)
        self.actionCase.triggered.connect(self.toolCaseTriggered)
        self.actionMessage_Infor.triggered.connect(self.toolMessageInforTriggered)
        self.actionTraceSetting.triggered.connect(self.toolTraceSettingTriggered)
        
        self.logger = logging.getLogger(LOGGING_NAME)
        
        self.actionUdsConsole.setEnabled(False)

        self.toolTxid = int(self.testerToolSettingForm.TxIdlineEdit.text(),16)
        self.toolRxid = int(self.testerToolSettingForm.RxIdlineEdit.text(),16)
        self.toolFuncTxid = int(self.testerToolSettingForm.FuncTxIdlineEdit.text(),16)
        self.toolChannel = self.testerToolSettingForm.ChannelcomboBox.currentText()
        self.toolBitrate = int(self.testerToolSettingForm.BitratelineEdit.text())
        self.initStatus = self.testerTool.initSetting(self.toolChannel,self.toolBitrate,self.toolTxid,self.toolRxid,self.toolFuncTxid)
        self.logger.debug('self.initStatus: %s',self.initStatus)
        self.actionUdsConsole.setEnabled(True)

    def toolUdsConsoleTriggered(self):
        self.testerToolUdsConsole.show()
        
    def toolCaseTriggered(self):
        self.testerToolCase.show()

    def toolMessageInforTriggered(self):
        self.testerToolMsg.show()
        # self.testerToolMsg.exec()

    def toolTraceSettingTriggered(self):
        self.testerToolMsgSetting.show()

        
    def onUpdateText(self,text):
        cursor = self.LogtextEdit.textCursor()  
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.LogtextEdit.setTextCursor(cursor)
        self.LogtextEdit.ensureCursorVisible()
    
    def toolSettingTriggered(self):
        self.testerToolSettingForm.show()
    
    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
        try:
            self.testerTool.canBus.stop_all_periodic_tasks()
            self.testerTool.canBus.shutdown()
            self.testerTool.canCom.close()
            self.canMsgRecFlag = False
        except:
            pass
        sys.exit(5)

    def testerInitSetting(self):
        self.toolChannel = self.testerToolSettingForm.ChannelcomboBox.currentText()
        self.toolBitrate = int(self.testerToolSettingForm.BitratelineEdit.text())
        if not self.toolBitrate:
            QMessageBox.information(self,'Channel Setting','init bitrate 500k',QMessageBox.Ok|QMessageBox.No)
        self.toolTxid = int(self.testerToolSettingForm.TxIdlineEdit.text(),16)
        self.toolRxid = int(self.testerToolSettingForm.RxIdlineEdit.text(),16)
        self.initStatus = self.testerTool.initSetting(self.toolChannel,self.toolBitrate,self.toolTxid,self.toolRxid,self.toolFuncTxid)

        self.logger.debug('toolChannel = %s', self.toolChannel)
        self.logger.debug('toolBitrate = %d', self.toolBitrate)
        self.logger.debug('toolTxid = %03x' ,self.toolTxid)
        self.logger.debug('toolRxid = %03x',self.toolRxid)

    def toolSendUdsMsg(self):
        if self.initStatus == 1:
            requestPdu = binascii.a2b_hex(self.SendlineEdit.text().replace(' ',''))
            tTH = threading.Thread(name='SendUdsPdu',target=self.testerTool.sendRequestPdu(requestPdu))
            tTH.start()
        elif self.initStatus == 0 :
            msgBoxInfot =  QMessageBox.warning(self,'init','Please init',QMessageBox.Yes|QMessageBox.No)
            if msgBoxInfot == QMessageBox.Yes:
                self.initStatus = self.testerTool.initSetting(self.toolChannel,self.toolBitrate,self.toolTxid,self.toolRxid,self.toolFuncTxid)
                self.logger.debug('toolChannel = %s', self.toolChannel)
                self.logger.debug('toolBitrate = %d', self.toolBitrate)
                self.logger.debug('toolTxid = %03x' ,self.toolTxid)
                self.logger.debug('toolRxid = %03x',self.toolRxid)
            else:
                self.closeEvent()
        else:
            msgBoxInfot =  QMessageBox.warning(self,'init','Please check device!',QMessageBox.Yes|QMessageBox.No)
            self.logger.error('please check device!')
            self.SendpushButton.setDisabled(True)

    def toolRecevieCanMsg(self):
        while self.canMsgRecFlag:
            canMsg = self.testerTool.canBus.recv()
            if canMsg:
                self.canMsgRecQueue.put(canMsg)



        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

